package com.huaxin.hxmoduleworkorder.common;

import org.springframework.stereotype.Component;

import java.util.Optional;

@Component
public class LocationUtils {

    private static final double EARTH_RADIUS_METERS = 6371000; // 地球半径，单位：米

    /**
     * 判断两个经纬度是否在指定距离内（默认 50 米）
     *
     * @param lat1            第一个点纬度
     * @param lon1            第一个点经度
     * @param lat2            第二个点纬度
     * @param lon2            第二个点经度
     * @param thresholdMeters 判断阈值（单位：米），如 50 米
     * @return true 表示两点距离 ≤ 阈值
     */
    public static boolean isWithinDistance(
            double lat1, double lon1,
            double lat2, double lon2,
            double thresholdMeters) {

        if (lat1 == lat2 && lon1 == lon2) {
            return true; // 完全相同，直接返回
        }

        double distance = calculateDistance(lat1, lon1, lat2, lon2);
        return distance <= thresholdMeters;
    }

    /**
     * 计算两点间距离（米）
     */
    public static double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return EARTH_RADIUS_METERS * c;
    }

    public static class Coordinate {
        public final double lon;
        public final double lat;

        private Coordinate(double lon, double lat) {
            this.lon = lon;
            this.lat = lat;
        }

        public static Optional<Coordinate> of(String lonStr, String latStr) {
            return parseDouble(lonStr)
                    .flatMap(lon -> parseDouble(latStr).map(lat -> new Coordinate(lon, lat)));
        }

        private static Optional<Double> parseDouble(String str) {
            if (str == null || str.trim().isEmpty()) return Optional.empty();
            try {
                return Optional.of(Double.parseDouble(str.trim()));
            } catch (NumberFormatException e) {
                return Optional.empty();
            }
        }
    }
}